using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using Caliburn.Micro;

namespace MediaOwl.Core.Modularity
{
    public class LoadedModules : IResult
    {
        private readonly IModuleManager moduleManager;
        private readonly Action<IEnumerable<Module>> onSuccess;
        private readonly Action<Exception> onFail;

        public LoadedModules(IModuleManager moduleManager, Action<IEnumerable<Module>> onSuccess = null, Action<Exception> onFail = null)
        {
            this.moduleManager = moduleManager;
            this.onSuccess = onSuccess;
            this.onFail = onFail;
        }

        [Import]
        public AggregateCatalog Catalog { get; set; }

        public void Execute(ActionExecutionContext context)
        {
            var depCatalogs = Catalog.Catalogs.OfType<DeploymentCatalog>();
            var moduleList = new List<Module>(depCatalogs.Count());
            try
            {
                foreach (var deploymentCatalog in depCatalogs)
                {
                    var module = moduleManager.Modules.FirstOrDefault(x => x.Uri == deploymentCatalog.Uri);
                    if (module != null)
                    {
                        module.Loaded = true;
                        moduleList.Add(module);
                    }
                }

                if (onSuccess != null)
                    Caliburn.Micro.Execute.OnUIThread(() => onSuccess(moduleList));

                Completed(this, new ResultCompletionEventArgs());
            }
            catch (Exception err)
            {
                if (onFail != null)
                    Caliburn.Micro.Execute.OnUIThread(() => onFail(err));
                Completed(this, new ResultCompletionEventArgs{Error = err});
            }
        }

        public event EventHandler<ResultCompletionEventArgs> Completed  = delegate{ };
    }
}